package edu.rit.drh4818.raytracing.object;

import edu.rit.drh4818.raytracing.util.Intersection;
import edu.rit.drh4818.raytracing.util.Ray;


/**
 * A sphere.
 * 
 * @author Darren Headrick
 * 
 */
public class Sphere extends SceneObject {

	/**
	 * Sphere's center coordinates.
	 */
	public double x,y,z;
	
	/**
	 * Radius.
	 */
	public double r;
	
	/**
	 * Create a new sphere.
	 * 
	 * @param x
	 *            X value of coordinates.
	 * @param y
	 *            Y value of coordinates.
	 * @param z
	 *            Z value of coordinates.
	 * @param r
	 *            radius of sphere.
	 * @param prop
	 *            Object properties.
	 */
	public Sphere( double x, double y, double z, double r, ObjectProperties prop )
	{
		super( prop );
		this.x = x; this.y = y; this.z = z;
		this.r = r;
	}
	
	/*
	 * Get the location of intersection with the sphere.
	 */
	public Intersection getIntersection(Ray ray) 
	{	
		 double A = Math.pow(ray.xd,2) + Math.pow(ray.yd,2) + Math.pow(ray.zd,2);
		 double B = 2 * (ray.xd * (ray.x0 - x) + ray.yd * (ray.y0 - y) + ray.zd * (ray.z0 - z));
		 double C = Math.pow(ray.x0 - x,2) + Math.pow(ray.y0 - y,2) +
		 					Math.pow(ray.z0 - z, 2)-Math.pow( r,2);
			    
		 double disc = B*B - 4*A*C;
		 if (disc < 0) return Intersection.NONE;
		 double sqrtdisc = Math.pow(disc,.5);
			    
		 double t = (-B - sqrtdisc) / (2*A);
		 if( t > 0 ) return new Intersection( t, this, ray );
		 t = (-B + sqrtdisc) / (2*A);
		 if( t > 0 ) return new Intersection( t, this, ray );
		 return Intersection.NONE;
	}
	
	/*
	 * Calculate the normal by directing a ray from center to the intersection.
	 *  Then setting the origin of normal, to the intersection point.
	 */
	public Ray getNormal(Intersection in) 
	{	
		double ix = in.getX(), iy = in.getY(), iz = in.getZ();
		Ray r = Ray.rayFromPoints( x, y, z, ix, iy, iz );
		return new Ray(ix, iy, iz, r.xd, r.yd, r.zd);		
	}
		
}